package com.cq.hd.order.processor.settle;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.cq.hd.common.enums.biz.*;
import com.cq.hd.common.response.Throw;
import com.cq.hd.common.utils.NoUtils;
import com.cq.hd.member.api.dto.MerchantAmtAddDto;
import com.cq.hd.member.api.dto.MerchantAmtBillSaveDto;
import com.cq.hd.member.api.vo.MerchantVo;
import com.cq.hd.order.api.dto.MonthSettleAmtUpdateDto;
import com.cq.hd.order.api.dto.MonthSettleGroupKeyDto;
import com.cq.hd.order.api.dto.OrderSettleBillDto;
import com.cq.hd.order.api.vo.OrderSettleBillVo;
import com.cq.hd.order.po.TbMonthSettleBillPo;
import com.cq.hd.order.po.TbOrderSettleBillItemPo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 伪月度结算 - 隔天将结算池商户本金写入月度结算表
 *
 * @author much
 * @since 2024/04/14 20:53
 */
@Slf4j
@Component
public class MerchantAmtDailySettleProcessor extends AbstractMonthSettleProcessor {

    @Override
    protected List<OrderSettleBillVo> queryWaitProcessBills() {
        OrderSettleBillDto param = new OrderSettleBillDto();
        param.setTradeType(OrderSettleBillTradeTypeEnum.MERCHANT_AMT.getValue());
        param.setMonthSettleState(MonthSettleStateEnum.WAIT.getValue());
        // 查询最近3天的记录
        Date endTime = DateUtil.beginOfDay(new Date());
        DateTime startDate = DateUtil.beginOfMonth(DateUtil.offsetDay(endTime, -3));
        param.setStartTradeTime(DateUtil.format(startDate, "yyyy-MM-dd HH:mm:ss"));
        param.setEndTradeTime(DateUtil.format(DateUtil.beginOfDay(endTime), "yyyy-MM-dd HH:mm:ss"));
        return orderSettleBillService.listByDto(param);
    }

    @Override
    protected TbMonthSettleBillPo getMonthSettleBill(MonthSettleGroupKeyDto groupKeyDto, List<OrderSettleBillVo> orderSettleBills) {
        TbMonthSettleBillPo tbMonthSettleBillPo = newMonthSettleBill(groupKeyDto, orderSettleBills, 1);
        TbMonthSettleBillPo oldMonthSettleBillPo = monthSettleBillMapper.selectLastOneByGroupKey(groupKeyDto);
        // 如果旧的月度结算单不为空，合并两个金额
        if (oldMonthSettleBillPo != null && oldMonthSettleBillPo.getStatus() == MonthSettleBillStatusEnum.NEW.getValue()) {
            MonthSettleAmtUpdateDto monthSettleAmtUpdateDto = new MonthSettleAmtUpdateDto();
            monthSettleAmtUpdateDto.setId(oldMonthSettleBillPo.getId());
            monthSettleAmtUpdateDto.setTradeChangeAmt(tbMonthSettleBillPo.getTradeAmt());
            monthSettleAmtUpdateDto.setReceiveChangeAmt(tbMonthSettleBillPo.getReceiveAmt());
            monthSettleAmtUpdateDto.setFeeChangeAmt(tbMonthSettleBillPo.getFeeAmt());
            monthSettleAmtUpdateDto.setStatus(MonthSettleBillStatusEnum.NEW.getValue());
            int res = monthSettleBillMapper.updateMonthSettleAmt(monthSettleAmtUpdateDto);
            if (res == 0) {
                Throw.isBusinessException("月度结算单更新失败");
            }
            return oldMonthSettleBillPo;
        } else {
            // save monthSettleBill
            monthSettleBillMapper.insert(tbMonthSettleBillPo);
            return tbMonthSettleBillPo;
        }
    }


    @Override
    protected MerchantAmtAddDto calculateMerchantAmtAddDto(Long merchantId, List<TbOrderSettleBillItemPo> orderSettleBillItems) {
        MerchantAmtAddDto merchantAmtAddDto = new MerchantAmtAddDto();
        merchantAmtAddDto.setId(merchantId);
        BigDecimal totalMerchantAmt = orderSettleBillItems.stream()
                .map(TbOrderSettleBillItemPo::getTradeAmt)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        merchantAmtAddDto.setBalanceAmt(totalMerchantAmt);
        merchantAmtAddDto.setSubsidyAmt(BigDecimal.ZERO);
        return merchantAmtAddDto;
    }

    @Override
    protected List<MerchantAmtBillSaveDto> generateMerchantAmtBills(MerchantVo merchantVo, List<TbOrderSettleBillItemPo> orderSettleBillItems) {
        List<MerchantAmtBillSaveDto> merchantAmtBillSaveList = new ArrayList<>(orderSettleBillItems.size());
        LocalDateTime now = LocalDateTime.now();
        for (TbOrderSettleBillItemPo item : orderSettleBillItems) {
            MerchantAmtBillSaveDto merchantAmtBillSaveDto = BeanUtil.copyProperties(item, MerchantAmtBillSaveDto.class);
            merchantAmtBillSaveDto.setBillNo(NoUtils.getMemberAmtBillNo());
            merchantAmtBillSaveDto.setBillType(BillTypeEnum.INCOME.getValue());
            merchantAmtBillSaveDto.setTradeType(MemberAmtBillTradeTypeEnum.ORDER_AMT.getValue());
            merchantAmtBillSaveDto.setRelationTradeNo(item.getSubOrderNo());
            merchantAmtBillSaveDto.setTradeTime(now);
            merchantAmtBillSaveDto.setCreateTime(now);
            merchantAmtBillSaveDto.setUpdateTime(now);
            merchantAmtBillSaveDto.setBeforeAmt(merchantVo.getBalanceAmt());
            merchantAmtBillSaveDto.setTradeAmt(item.getTradeAmt());
            merchantAmtBillSaveDto.setAfterAmt(merchantAmtBillSaveDto.getBeforeAmt().add(item.getTradeAmt()));
            merchantAmtBillSaveList.add(merchantAmtBillSaveDto);
            // 更新一下商户余额
            merchantVo.setBalanceAmt(merchantAmtBillSaveDto.getAfterAmt());
        }
        return merchantAmtBillSaveList;
    }

}
